package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.TeamBuyOrderRepository;
import com.xinhe.web.reposity.TeamBuyRepository;
import com.xinhe.web.reposity.ValueConfigRepository;
import com.xinhe.web.response.TeamBuyDetailView;
import com.xinhe.web.response.TeamBuyOrderMemberView;
import com.xinhe.web.response.TeamBuyView;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.util.*;

@Service
public class TeamBuyService {
    @Autowired
    private TeamBuyRepository teamBuyRepository;
    @Autowired
    private TeamBuyOrderRepository teamBuyOrderRepository;
    /*@Autowired
    private ValueConfigCache valueConfigCache;*/
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderPayService orderPayService;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @Autowired
    ValueConfigRepository valueConfigRepository;

    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    public QueryResults<TeamBuyView> pageTeamBuy(Long leaderUserId, Long teamGoodsId, Long goodsId, Integer memberAmount,
                                                 Integer joinAmount, Integer payAmount, String status,
                                                 Date startTime, Date endTime, String remark, Integer progress,
                                                 int pageNum, int pageSize) {
        QTeamBuy qTeamBuy = QTeamBuy.teamBuy;
        QMember qMember = QMember.member;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qTeamBuy.removed.eq(0));
        if (!Objects.isNull(leaderUserId)) {
            builder.and(qTeamBuy.leaderUserId.eq(leaderUserId));
        }
        if (!Objects.isNull(teamGoodsId)) {
            builder.and(qTeamBuy.teamGoodsId.eq(teamGoodsId));
        }
        if (!Objects.isNull(goodsId)) {
            builder.and(qTeamBuy.goodsId.eq(goodsId));
        }
        if (!Objects.isNull(memberAmount)) {
            builder.and(qTeamBuy.memberAmount.eq(memberAmount));
        }
        if (!Objects.isNull(joinAmount)) {
            builder.and(qTeamBuy.joinAmount.eq(joinAmount));
        }
        if (!Objects.isNull(payAmount)) {
            builder.and(qTeamBuy.payAmount.eq(payAmount));
        }
        if (StringUtils.isNotBlank(status)) {
            builder.and(qTeamBuy.status.eq(status));
        }
        if (!Objects.isNull(startTime)) {
            builder.and(qTeamBuy.startTime.eq(startTime));
        }
        if (!Objects.isNull(endTime)) {
            builder.and(qTeamBuy.endTime.eq(endTime));
        }
        if (!Objects.isNull(progress) && 1== progress) {
            builder.and(qTeamBuy.memberAmount.gt(qTeamBuy.joinAmount));
        }
        QueryResults<TeamBuyView> teamBuyViewQueryResults = queryFactory.select(
                Projections.bean(
                        TeamBuyView.class,
                        qTeamBuy.startTime,
                        qTeamBuy.endTime,
                        qTeamBuy.goodsId,
                        qTeamBuy.joinAmount,
                        qTeamBuy.leaderUserId,
                        qTeamBuy.memberAmount,
                        qTeamBuy.payAmount,
                        qTeamBuy.status,
                        qTeamBuy.teamGoodsId,
                        qMember.nickname.as("leaderUsername"),
                        qMember.iconPath.as("leaderIconPath")
                )
        ).from(qTeamBuy)
                .leftJoin(qMember).on(qTeamBuy.leaderUserId.eq(qMember.fUserId))
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();

        List<TeamBuyView> results = teamBuyViewQueryResults.getResults();
        // 创建一个用于存储修改后元组对象的列表
        List<TeamBuyView> modifiedResults = new ArrayList<>();
        // 遍历分页记录，进行字段值重新赋值
        //Integer teamTimeoutHour = this.valueConfigCache.getInteger("team-buy-timeout-hour", Integer.valueOf(24));
        Integer teamTimeoutHour = 24;
        Calendar calendar = Calendar.getInstance();
        for (TeamBuyView teamBuyView : results) {
            calendar.setTime(teamBuyView.getStartTime());
            calendar.add(11, teamTimeoutHour.intValue());
            teamBuyView.setEndTime(calendar.getTime());
            // 将修改后的元组对象添加到列表中
            modifiedResults.add(teamBuyView);
        }
        // 创建一个新的QueryResults对象，包含修改后的分页记录
        QueryResults<TeamBuyView> modifiedQueryResults = new QueryResults<>(
                modifiedResults,
                teamBuyViewQueryResults.getTotal(),
                teamBuyViewQueryResults.getOffset(),
                teamBuyViewQueryResults.getLimit()
        );
        return modifiedQueryResults;
    }



    public QueryResults<TeamBuyView> pageTeamBuyPlatform(Long leaderUserId, Long teamGoodsId, Long goodsId, Integer memberAmount,
                                                         Integer joinAmount, Integer payAmount, String status,
                                                         Date startTime, Date endTime, String remark, Integer progress,
                                                         int pageNum, int pageSize) {
        QTeamBuy qTeamBuy = QTeamBuy.teamBuy;
        QMember qMember = QMember.member;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qTeamBuy.removed.eq(0));
        if (StringUtils.isNotBlank(status)) {
            builder.and(qTeamBuy.status.eq(status));
        }
        QueryResults<TeamBuyView> teamBuyViewQueryResults = queryFactory.select(
                Projections.bean(
                        TeamBuyView.class,
                        qTeamBuy.startTime,
                        qTeamBuy.endTime,
                        qTeamBuy.goodsId,
                        qTeamBuy.joinAmount,
                        qTeamBuy.leaderUserId,
                        qTeamBuy.memberAmount,
                        qTeamBuy.payAmount,
                        qTeamBuy.status,
                        qTeamBuy.teamGoodsId,
                        qMember.nickname.as("leaderUsername"),
                        qMember.iconPath.as("leaderIconPath")
                )
        ).from(qTeamBuy)
                .leftJoin(qMember).on(qTeamBuy.leaderUserId.eq(qMember.fUserId))
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
        return teamBuyViewQueryResults;
    }

    @Transactional
    public void saveTeamBuyTimeoutInterval() {
        Integer teamTimeoutHour = 24;
        //获取配置的拼团超时小时,24
        Optional<ValueConfig> valueConfig = valueConfigRepository.findById("team-buy-timeout-hour");
        if (valueConfig.isPresent() && StringUtils.isNotBlank(valueConfig.get().getValue())){
            teamTimeoutHour = Integer.valueOf(valueConfig.get().getValue());
        }
        List<TeamBuy> timeoutTeamBuys = this.teamBuyRepository.findByTimeout(teamTimeoutHour);
        if (CollectionUtils.isNotEmpty(timeoutTeamBuys)) {
            for (TeamBuy teamBuy : timeoutTeamBuys) {
                teamBuy.setStatus("FAILURE");
                teamBuy.setEndTime(new Date());
                this.teamBuyRepository.saveAndFlush(teamBuy);
                List<TeamBuyOrder> teamOrders = this.teamBuyOrderRepository.findByTeamByTimeout(teamBuy.getId());
                if (CollectionUtils.isNotEmpty(teamOrders)) {
                    for (TeamBuyOrder teamOrder : teamOrders) {
                        teamOrder.setStatus("FAILURE");
                        this.teamBuyOrderRepository.saveAndFlush(teamOrder);
                        Result<String> result = this.orderPayService.saveRefund(teamOrder.getOrderId());
                        if (0==result.getCode() && "SUCCESS".equals(result.getData())) {
                            this.orderService.cancelOrder(teamOrder.getOrderId());
                        }
                    }
                }
            }
        }
    }

    public Result<TeamBuyDetailView> detailTeamBuy(Long teamBuyId) {
        TeamBuyDetailView view = new TeamBuyDetailView();
        TeamBuy teamBuy = teamBuyRepository.findById(teamBuyId).get();
        if (teamBuy != null) {
            BeanUtils.copyProperties(teamBuy, view);
            view.setStatus((teamBuy.getStatus() != null) ? teamBuy.getStatus() : null);
            Calendar instance = Calendar.getInstance();
            instance.setTime(view.getStartTime());
            if (teamBuy.getStatus() == null) {
                //Integer teamTimeoutMinuteStr = this.valueConfigCache.getInteger("team-pay-timeout-minute", Integer.valueOf(30));
                Integer teamTimeoutMinuteStr = 30;
                instance.add(12, teamTimeoutMinuteStr.intValue());
            } else if (teamBuy.getStatus().equals("TEAMING")) {
                //Integer teamTimeoutHour = this.valueConfigCache.getInteger("team-buy-timeout-hour", Integer.valueOf(24));
                Integer teamTimeoutHour = 24;
                instance.add(11, teamTimeoutHour.intValue());
            }
            view.setEndTime(instance.getTime());

            List<String> stringList = new ArrayList<>();
            stringList.add("PAYED");
            stringList.add("SUCCESS");
            QTeamBuy qTeamBuy = QTeamBuy.teamBuy;
            QTeamBuyOrder qTeamBuyOrder = QTeamBuyOrder.teamBuyOrder;
            QMember qMember = QMember.member;
            BooleanBuilder builder = new BooleanBuilder();
            //builder.and(qTeamBuy.removed.eq(0));
            if (!Objects.isNull(teamBuyId)) {
                builder.and(qTeamBuy.id.eq(teamBuyId));
            }
            if (qTeamBuy.leaderUserId.equals(qTeamBuyOrder.buyerUserId)) {
                builder.and(qTeamBuyOrder.status.in(stringList));
            }
            List<TeamBuyOrderMemberView> viewList = queryFactory.select(
                    Projections.bean(
                            TeamBuyOrderMemberView.class,
                            qTeamBuy.startTime,
                            qTeamBuy.endTime,
                            qTeamBuy.goodsId,
                            qTeamBuy.joinAmount,
                            qTeamBuy.leaderUserId,
                            qTeamBuy.memberAmount,
                            qTeamBuy.payAmount,
                            qTeamBuy.status,
                            qTeamBuy.teamGoodsId,
                            qMember.nickname.as("leaderUsername"),
                            qMember.iconPath.as("leaderIconPath")
                    )
            ).from(qTeamBuy)
                    .leftJoin(qTeamBuyOrder).on(qTeamBuy.id.eq(qTeamBuyOrder.teamBuyId))
                    .leftJoin(qMember).on(qTeamBuy.leaderUserId.eq(qMember.fUserId))
                    .where(builder).fetch();

            view.setMemberViews(viewList);
        }
        return Result.ok(view);
    }


    public Result delete(Long teamBuyId) {
        teamBuyRepository.deleteById(teamBuyId);
        return Result.ok();
    }

    public Result saveModel(Long leaderUserId, Long teamGoodsId, Long goodsId, Integer memberAmount, Integer joinAmount, Integer payAmount, String status, Date startTime, Date endTime, String remark) {
        TeamBuy teamBuy = new TeamBuy();
        teamBuyRepository.save(teamBuy);
        return Result.ok();
    }
}
